import axios, { AxiosRequestConfig, CancelTokenSource } from 'axios';

const cancelTokens: Map<symbol, CancelTokenSource> = new Map();

export const CancelUtil = {
  /**
   * @author 戴俊明 <idaijunming@163.com>
   * @description 生成 Key 与 CancelToken
   * @date 2020/3/12 16:51
   **/
  source: (): symbol => {
    const key = Symbol();
    cancelTokens.set(key, axios.CancelToken.source());
    return key;
  },

  /**
   * @author 戴俊明 <idaijunming@163.com>
   * @description 通过 Key 取消请求
   * @date 2020/3/12 16:51
   **/
  cancel: (key: symbol, message?: string): void => {
    const source = cancelTokens.get(key);
    if (source) {
      source.cancel(message);
      cancelTokens.delete(key);
    }
  },

  /**
   * @author 戴俊明 <idaijunming@163.com>
   * @description 判断此错误是否是由于取消请求引发的
   * @date 2020/3/12 16:50
   **/
  isCancel: (error?: Error): boolean => axios.isCancel(error),

  /**
   * @author 戴俊明 <idaijunming@163.com>
   * @description 通过 Key 创建一个可以取消的请求配置
   * @date 2020/3/12 16:50
   **/
  create: (key: symbol, config: AxiosRequestConfig): AxiosRequestConfig => {
    const source = cancelTokens.get(key);
    if (source) {
      config.cancelToken = source.token;
    }
    return config;
  },

  /**
   * @author 戴俊明 <idaijunming@163.com>
   * @description 创建一个可以取消的请求配置
   * @date 2020/3/12 17:12
   **/
  build: (config: AxiosRequestConfig): [symbol, AxiosRequestConfig] => {
    const key = CancelUtil.source();
    return [key, CancelUtil.create(key, config)];
  },
};
